package com.joe.blockview;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ScrollView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.joe.blockview.model.Connection;
import com.joe.blockview.model.Oprate;
import com.joe.blockview.model.Plain;
import com.joe.blockview.service.GenelateCommandService;
import com.joe.blockview.ui.BlockBackView;
import com.joe.blockview.ui.BlockEndView;
import com.joe.blockview.ui.BlockForwardView;
import com.joe.blockview.ui.BlockIfView;
import com.joe.blockview.ui.BlockLeftView;
import com.joe.blockview.ui.BlockPressView;
import com.joe.blockview.ui.BlockRepeatView;
import com.joe.blockview.ui.BlockRightView;
import com.joe.blockview.ui.BlockStartView;
import com.joe.blockview.ui.BlockTouchView;
import com.joe.blockview.ui.BlockView;
import com.joe.blockview.ui.BlockVoiceView;
import com.joe.blockview.ui.WorkSpace;
import com.joe.blockview.utils.DialogUtils;
import com.joe.blockview.utils.PlainUtils;
import com.joe.blockview.utils.SharedPreUtils;
import com.joe.keyboard.KeyBoardView;

import java.util.ArrayList;
import java.util.List;

public class WorkSpaceFragment extends Fragment implements View.OnClickListener {

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.layout_workspace_fragment, null);
        return v;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        init();
    }

    private WorkSpace workspace;
    private ScrollView workspace_plain_sv;
    private RecyclerView workspace_plain_ry;
    private ScrollView blockview_scrollview;

    private KeyBoardView workspace_keyboard;

    private void init() {
        ////////////////////////////////
        workspace = getView().findViewById(R.id.block_workspace);
        blockview_scrollview = getView().findViewById(R.id.blockview_scrollview);
        workspace_plain_sv = getView().findViewById(R.id.workspace_plain_sv);
        workspace_plain_ry = getView().findViewById(R.id.workspace_plain_ry);
        workspace_keyboard = getView().findViewById(R.id.workspace_keyboard);
        workspace.addKeyBoard(workspace_keyboard);

        getView().findViewById(R.id.workspace_fragment).setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                workspace_plain_sv.setVisibility(View.GONE);
                workspace_keyboard.setVisibility(View.GONE);
                return false;
            }
        });

        workspace.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                workspace_plain_sv.setVisibility(View.GONE);
                workspace_keyboard.setVisibility(View.GONE);
            }
        });

        //workspace.addView(new SeekBar(WorkSpaceActivity.this));

        getView().findViewById(R.id.block_back).setOnClickListener(this);
        getView().findViewById(R.id.block_end).setOnClickListener(this);
        getView().findViewById(R.id.block_forword).setOnClickListener(this);
        getView().findViewById(R.id.block_if).setOnClickListener(this);
        getView().findViewById(R.id.block_left).setOnClickListener(this);
        getView().findViewById(R.id.block_press).setOnClickListener(this);
        getView().findViewById(R.id.block_repeat).setOnClickListener(this);
        getView().findViewById(R.id.block_right).setOnClickListener(this);
        getView().findViewById(R.id.block_start).setOnClickListener(this);
        getView().findViewById(R.id.block_touch).setOnClickListener(this);
        getView().findViewById(R.id.block_voice).setOnClickListener(this);

        ////////////////tool////////////////////////////////////
        getView().findViewById(R.id.tool_event).setSelected(true);
        getView().findViewById(R.id.blockview_back).setOnClickListener(clickListener);
        getView().findViewById(R.id.tool_control).setOnClickListener(clickListener);
        getView().findViewById(R.id.tool_event).setOnClickListener(clickListener);
        getView().findViewById(R.id.tool_action).setOnClickListener(clickListener);
        getView().findViewById(R.id.tool_detect).setOnClickListener(clickListener);
        getView().findViewById(R.id.tool_voice).setOnClickListener(clickListener);


        getView().findViewById(R.id.workspace_run).setOnClickListener(clickListener);
        getView().findViewById(R.id.block_plain).setOnClickListener(clickListener);
        getView().findViewById(R.id.block_save).setOnClickListener(clickListener);

        initPalinData();


        Intent intent = new Intent(getContext(), GenelateCommandService.class);
        getActivity().bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
    }

    /**
     * 解析命令服务
     */
    private GenelateCommandService.MyBinder myBinder;
    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            myBinder = (GenelateCommandService.MyBinder) service;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////

    //////////////////////////////////////////////////////////////////////////////
    /////////////////////-----点击事件，添加block模块-----////////////////////////
    //////////////////////////////////////////////////////////////////////////////
    private BlockView blockView;

    @Override
    public void onClick(View v) {
        workspace_plain_sv.setVisibility(View.GONE);
        workspace_keyboard.setVisibility(View.GONE);
        int i = v.getId();
        if (i == R.id.block_back) {
            blockView = new BlockBackView(getContext());
            blockView.setPosition(workspace.getScrollX(), v.getTop() + workspace.getScrollY(), workspace.getScrollX() + blockView.getMeasuredWidth(), v.getTop() + workspace.getScrollY() + blockView.getMeasuredHeight());
            blockView.getConnection().getWorkspacePoint().x = workspace.getScrollX();
            blockView.getConnection().getWorkspacePoint().y = v.getTop() + workspace.getScrollY();
            workspace.addView(blockView);
        } else if (i == R.id.block_end) {
            blockView = new BlockEndView(getContext());
            blockView.setPosition(workspace.getScrollX(), v.getTop() + workspace.getScrollY(), workspace.getScrollX() + blockView.getMeasuredWidth(), v.getTop() + workspace.getScrollY() + blockView.getMeasuredHeight());
            blockView.getConnection().getWorkspacePoint().x = workspace.getScrollX();
            blockView.getConnection().getWorkspacePoint().y = v.getTop() + workspace.getScrollY();
            workspace.addView(blockView);
        } else if (i == R.id.block_forword) {
            blockView = new BlockForwardView(getContext());
            blockView.setPosition(workspace.getScrollX(), v.getTop() + workspace.getScrollY(), workspace.getScrollX() + blockView.getMeasuredWidth(), v.getTop() + workspace.getScrollY() + blockView.getMeasuredHeight());
            blockView.getConnection().getWorkspacePoint().x = workspace.getScrollX();
            blockView.getConnection().getWorkspacePoint().y = v.getTop() + workspace.getScrollY();
            workspace.addView(blockView);
        } else if (i == R.id.block_if) {
            blockView = new BlockIfView(getContext());
            blockView.setPosition(workspace.getScrollX(), v.getTop() + workspace.getScrollY(), workspace.getScrollX() + blockView.getMeasuredWidth(), v.getTop() + workspace.getScrollY() + blockView.getMeasuredHeight());
            blockView.getConnection().getWorkspacePoint().x = workspace.getScrollX();
            blockView.getConnection().getWorkspacePoint().y = v.getTop() + workspace.getScrollY();
            workspace.addView(blockView);
        } else if (i == R.id.block_left) {
            blockView = new BlockLeftView(getContext());
            blockView.setPosition(workspace.getScrollX(), v.getTop() + workspace.getScrollY(), workspace.getScrollX() + blockView.getMeasuredWidth(), v.getTop() + workspace.getScrollY() + blockView.getMeasuredHeight());
            blockView.getConnection().getWorkspacePoint().x = workspace.getScrollX();
            blockView.getConnection().getWorkspacePoint().y = v.getTop() + workspace.getScrollY();
            workspace.addView(blockView);
        } else if (i == R.id.block_press) {
            blockView = new BlockPressView(getContext());
            blockView.setPosition(workspace.getScrollX(), v.getTop() + workspace.getScrollY(), workspace.getScrollX() + blockView.getMeasuredWidth(), v.getTop() + workspace.getScrollY() + blockView.getMeasuredHeight());
            blockView.getConnection().getWorkspacePoint().x = workspace.getScrollX();
            blockView.getConnection().getWorkspacePoint().y = v.getTop() + workspace.getScrollY();
            workspace.addView(blockView);
        } else if (i == R.id.block_repeat) {
            blockView = new BlockRepeatView(getContext());
            blockView.setPosition(workspace.getScrollX(), v.getTop() + workspace.getScrollY(), workspace.getScrollX() + blockView.getMeasuredWidth(), v.getTop() + workspace.getScrollY() + blockView.getMeasuredHeight());
            blockView.getConnection().getWorkspacePoint().x = workspace.getScrollX();
            blockView.getConnection().getWorkspacePoint().y = v.getTop() + workspace.getScrollY();
            workspace.addView(blockView);
        } else if (i == R.id.block_right) {
            blockView = new BlockRightView(getContext());
            blockView.setPosition(workspace.getScrollX(), v.getTop() + workspace.getScrollY(), workspace.getScrollX() + blockView.getMeasuredWidth(), v.getTop() + workspace.getScrollY() + blockView.getMeasuredHeight());
            blockView.getConnection().getWorkspacePoint().x = workspace.getScrollX();
            blockView.getConnection().getWorkspacePoint().y = v.getTop() + workspace.getScrollY();
            workspace.addView(blockView);
        } else if (i == R.id.block_start) {
            blockView = new BlockStartView(getContext());
            blockView.setPosition(workspace.getScrollX(), v.getTop() + workspace.getScrollY(), workspace.getScrollX() + blockView.getMeasuredWidth(), v.getTop() + workspace.getScrollY() + blockView.getMeasuredHeight());
            blockView.getConnection().getWorkspacePoint().x = workspace.getScrollX();
            blockView.getConnection().getWorkspacePoint().y = v.getTop() + workspace.getScrollY();
            workspace.addView(blockView);
        } else if (i == R.id.block_touch) {
            blockView = new BlockTouchView(getContext());
            blockView.setPosition(workspace.getScrollX(), v.getTop() + workspace.getScrollY(), workspace.getScrollX() + blockView.getMeasuredWidth(), v.getTop() + workspace.getScrollY() + blockView.getMeasuredHeight());
            blockView.getConnection().getWorkspacePoint().x = workspace.getScrollX();
            blockView.getConnection().getWorkspacePoint().y = v.getTop() + workspace.getScrollY();
            workspace.addView(blockView);
        } else if (i == R.id.block_voice) {
            blockView = new BlockVoiceView(getContext());
            blockView.setPosition(workspace.getScrollX(), v.getTop() + workspace.getScrollY(), workspace.getScrollX() + blockView.getMeasuredWidth(), v.getTop() + workspace.getScrollY() + blockView.getMeasuredHeight());
            blockView.getConnection().getWorkspacePoint().x = workspace.getScrollX();
            blockView.getConnection().getWorkspacePoint().y = v.getTop() + workspace.getScrollY();
            workspace.addView(blockView);
        }
    }
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////


    ////////////////////////////////////////////////////////////////////////////////
    /////////////////////////------初始化方案列表----------/////////////////////////
    ///////////////////////////////////////////////////////////////////////////////
    private List<Plain> plains = null;
    private PlainAdapter adapter;
    private boolean isSelectPlain = false;
    private Plain selectedPlain = null;

    private void initPalinData() {
        plains = SharedPreUtils.getPlainList(getContext());
        workspace_plain_ry.setLayoutManager(new LinearLayoutManager(getContext()));
        adapter = new PlainAdapter(getContext(), plains, new OnItemClickListener() {
            @Override
            public void onClick(View v, Plain plain) {
                isSelectPlain = true;
                selectedPlain = plain;
                List<List<Oprate>> ops = PlainUtils.getPlain(getContext(), plain.getFileName());
                if (ops != null) {
                    //先清除之前的block
                    workspace.removeAllViews();
                    //解析，显示在workspace
                    workspace.addTrash();
                    showBlocks(ops);
                }
                workspace_plain_sv.setVisibility(View.GONE);
                workspace_keyboard.setVisibility(View.GONE);
            }
        });
        workspace_plain_ry.setAdapter(adapter);
    }

    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////

    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////tool----menu//////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    /**
     * 控制菜单栏选择监听
     */
    private View.OnClickListener clickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int i = v.getId();
            if (i == R.id.blockview_back) {
                getActivity().finish();
            } else if (i == R.id.tool_event) {
                unSelected();
                getActivity().findViewById(R.id.tool_event).setSelected(true);
                blockview_scrollview.scrollTo(0, 0);
            } else if (i == R.id.tool_control) {
                unSelected();
                getActivity().findViewById(R.id.tool_control).setSelected(true);
                blockview_scrollview.scrollTo(0, getActivity().findViewById(R.id.ly_control).getTop());
            } else if (i == R.id.tool_action) {
                unSelected();
                getActivity().findViewById(R.id.tool_action).setSelected(true);
                blockview_scrollview.scrollTo(0, getActivity().findViewById(R.id.ly_action).getTop());
            } else if (i == R.id.tool_detect) {
                unSelected();
                getActivity().findViewById(R.id.tool_detect).setSelected(true);
                blockview_scrollview.scrollTo(0, getActivity().findViewById(R.id.ly_detect).getTop());
            } else if (i == R.id.tool_voice) {
                unSelected();
                getActivity().findViewById(R.id.tool_voice).setSelected(true);
                blockview_scrollview.scrollTo(0, getActivity().findViewById(R.id.ly_voice).getTop());
            } else if (i == R.id.workspace_run) {
                if (myBinder != null) {
                    List<Connection> connections = new ArrayList<>();
                    connections.addAll(workspace.block.getAllConnections());
                    List<List<Oprate>> oprates = myBinder.paraserCon(connections);
                }
            } else if (i == R.id.block_plain) {
                workspace_plain_sv.setVisibility(View.VISIBLE);
            } else if (i == R.id.block_save) {
                final List<Connection> connections = new ArrayList<>();
                connections.addAll(workspace.block.getAllConnections());
                if (connections.size() == 0) {
                    Toast.makeText(getContext(), "没有可保存的方案！", Toast.LENGTH_SHORT).show();
                } else {
                    if (isSelectPlain) {
                        DialogUtils.showNotifyDialog(getContext(), "保存方案", "是否保存修改？", new DialogUtils.DialogConfireListener() {

                            @Override
                            public void onConfire(String name) {
                                //保存旧方案
                                //由于关联中有相互引用，无法直接转为json，所以使用解析后的数据保存
                                List<List<Oprate>> oprates = myBinder.paraserCon(connections);
                                PlainUtils.savePlain(getContext(), selectedPlain.getFileName(), oprates);
                                Toast.makeText(getContext(), "保存成功！", Toast.LENGTH_SHORT).show();
                            }
                        });

                    } else {
                        //新建方案
                        DialogUtils.showEditDialog(getContext(), "方案名称", new DialogUtils.DialogConfireListener() {
                            @Override
                            public void onConfire(String name) {
                                if (!name.isEmpty()) {
                                    //先保存方案列表
                                    Plain plain = new Plain();
                                    plain.setName(name);
                                    plain.setFileName("plain_" + System.currentTimeMillis());
                                    plains.add(plain);
                                    SharedPreUtils.savePlains(getContext(), plains);

                                    //再保存方案具体内容
                                    //由于关联中有相互引用，无法直接转为json，所以使用解析后的数据保存
                                    List<List<Oprate>> oprates = myBinder.paraserCon(connections);
                                    PlainUtils.savePlain(getContext(), plain.getFileName(), oprates);
                                    Toast.makeText(getContext(), "保存成功！", Toast.LENGTH_SHORT).show();
                                    adapter.notifyDataSetChanged();
                                }
                            }
                        });
                    }

                }
            }
        }
    };


    /**
     * 取消选中
     */
    private void unSelected() {
        workspace_plain_sv.setVisibility(View.GONE);
        workspace_keyboard.setVisibility(View.GONE);
        getActivity().findViewById(R.id.tool_event).setSelected(false);
        getActivity().findViewById(R.id.tool_control).setSelected(false);
        getActivity().findViewById(R.id.tool_action).setSelected(false);
        getActivity().findViewById(R.id.tool_detect).setSelected(false);
        getActivity().findViewById(R.id.tool_voice).setSelected(false);
    }

    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////

    ////////////////////////////////////////////////////////////////////////////////
    //////////////////////////-------方案显示方法--------------------///////////////
    ////////////////////////////////////////////////////////////////////////////////
    private void showBlocks(List<List<Oprate>> ops) {
        for (int i = 0; i < ops.size(); i++) {
            showBlockLines(ops.get(i), null);
        }
    }

    private void showBlockLines(List<Oprate> ops, BlockView blockView) {
        List<BlockView> blockViews = new ArrayList<>();
        for (int j = 0; j < ops.size(); j++) {
            Oprate oprates1 = ops.get(j);
            BlockView bv1 = getBlockView(oprates1);
            bv1.setPosition((int) oprates1.getWorkspacePoint().x, (int) oprates1.getWorkspacePoint().y, (int) oprates1.getWorkspacePoint().x + bv1.getSelfWidth(), (int) oprates1.getWorkspacePoint().y + bv1.getSelfHeight() + bv1.getBLength());
            bv1.getConnection().setWorkspacePoint(oprates1.getWorkspacePoint());
            //先生成所有block，后添加关联
            //输入关联先添加
            Oprate op = oprates1.getInPutOprate();
            if (op != null) {
                BlockView bv2 = getBlockView(op);
                bv1.getConnection().setInputCanConnect(false);
                bv1.getConnection().connectionInput(bv2.getConnection());

                bv2.getConnection().setInputCanConnect(false);
                bv2.getConnection().connectionInput(bv1.getConnection());
                bv2.setPosition((int) op.getWorkspacePoint().x, (int) op.getWorkspacePoint().y, (int) op.getWorkspacePoint().x + bv2.getSelfWidth(), (int) op.getWorkspacePoint().y + bv2.getSelfHeight() + bv1.getBLength());
                bv2.getConnection().setWorkspacePoint(op.getWorkspacePoint());

            }


            blockViews.add(bv1);
        }

        for (int j = 0; j < blockViews.size(); j++) {
            if (blockView != null && j == 0) {
                //添加唯一特殊neibu关联
                blockView.getConnection().connectionNext(blockViews.get(0).getConnection());
                blockView.getConnection().setNextConnect(false);

                blockViews.get(0).getConnection().connectionPre(blockView.getConnection());
                blockViews.get(0).getConnection().setPreCanConnect(false);
            }
            BlockView blv = blockViews.get(j);
            //添加下连接关联
            if (j < blockViews.size() - 1) {
                blv.getConnection().connectionTag(blockViews.get(j + 1).getConnection());
                blv.getConnection().setCanConnect(false);
                blockViews.get(j + 1).getConnection().connectionPre(blv.getConnection());
                blockViews.get(j + 1).getConnection().setPreCanConnect(false);
            }
            workspace.addView(blv);
            if (blv.getConnection().getInputConnection() != null) {
                workspace.addView(blv.getConnection().getInputConnection().getTagBlockView());
            }

            Oprate oprates1 = ops.get(j);
            List<Oprate> oprates = oprates1.getInOprate();
            if (oprates != null && oprates.size() > 0) {
                showBlockLines(oprates, blv);
            }
        }
    }

    private BlockView getBlockView(Oprate oprate) {
        BlockView blockView = null;
        switch (oprate.getType()) {
            case -1:
                blockView = new BlockEndView(getContext());
                break;
            case 0:
                blockView = new BlockStartView(getContext());
                break;
            case 1:
                switch (oprate.getCommand()) {
                    case "Left":
                        blockView = new BlockLeftView(getContext());
                        break;
                    case "Right":
                        blockView = new BlockRightView(getContext());
                        break;
                    case "Back":
                        blockView = new BlockBackView(getContext());
                        break;
                    case "Forward":
                        blockView = new BlockForwardView(getContext());
                        break;
                    case "Voice":
                        blockView = new BlockVoiceView(getContext());
                        break;
                }
                break;
            case 2:
                blockView = new BlockIfView(getContext());
                break;
            case 3:
                blockView = new BlockRepeatView(getContext());
                break;
            case 4:
                switch (oprate.getCommand()) {
                    case "Press":
                        blockView = new BlockPressView(getContext());
                        break;
                    case "Touch":
                        blockView = new BlockTouchView(getContext());
                        break;
                }
                break;
        }
        return blockView;
    }
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////


    @Override
    public void onDestroy() {
        getActivity().unbindService(serviceConnection);
        super.onDestroy();
    }
}
